/* Copyright 2007 Gearbox Software - http://www.gearboxsoft.com
 
 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at
 
     http:www.apache.org/licenses/LICENSE-2.0
 
 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.*/
/// <summary>
/// Summary description for TagCloudComponent
/// </summary>
namespace GearBlog.Web.ViewComponents
{
	using System;
	using System.Collections;
	using Castle.ActiveRecord;
	using Castle.MonoRail.Framework;
	using GearBlog.Web.Models;
	using NHibernate;

	public class TagCloudComponent:ViewComponent
    {
        private const int _tagCloudLevel = 5;
        public override void Initialize()
        {
            ArrayList result = (ArrayList) ActiveRecordMediator.ExecuteQuery(new TagCloudQuery());
            ArrayList tagCloudItems = new ArrayList();
            // find out max and min of post count
            int minCount=0, maxCount=0, range=0;
            if (result.Count > 0)
            {
                // init value first
                minCount = Convert.ToInt32(((object[])result[0])[1]);
                maxCount = minCount;

                foreach (object[] resultEntry in result)
                {
                    int postCount = Convert.ToInt32(resultEntry[1]);
                    if (postCount > maxCount) maxCount = postCount;
                    if (postCount < minCount) minCount = postCount;
                }
            }

            range = (int)Math.Ceiling(((double)(maxCount - minCount) / _tagCloudLevel));

            foreach (object[] resultEntry in result)
            {
                int postCount=Convert.ToInt32(resultEntry[1]);
                tagCloudItems.Add(new TagCloudItem(CalculateLevel(postCount, range, minCount), postCount, (Tag)resultEntry[0]));

            }

            PropertyBag["TagCloudItems"] = tagCloudItems;

        }

        private int CalculateLevel(int postCount, int range, int minPostCount)
        {
            if (range == 0) return 1;
            return (int)Math.Ceiling((double)(postCount-minPostCount / range)) + 1;;
        }        
    }


    public class TagCloudItem
    {
        private int _level;
        private int _postsCount;
        private Tag _tag;

        public TagCloudItem(int level, int postCount, Tag tag)
        {
            _level = level;
            _postsCount = postCount;
            _tag = tag;
        }
        public int Level
        {
            get { return _level; }
            set { _level = value; }
        }

        public int PostsCount
        {
            get { return _postsCount; }
            set { _postsCount = value; }
        }

        public Tag Tag
        {
            get { return _tag; }
            set { _tag = value; }
        }
    }

    public class TagCloudQuery : ActiveRecordBaseQuery
    {
        public TagCloudQuery():base(typeof(Tag)) 
        {
        }
        protected override IQuery CreateQuery(ISession session)
        {
            return session.CreateQuery("select tag, count(elements(tag.Posts)) from Tag tag group by tag.Id, tag.Name");
            
        }
        
    }
}
